package com.thread.concurrentTest;

import org.junit.Test;

import java.util.Random;
import java.util.concurrent.CountDownLatch;

public class CountDownLatchTest {

    @Test
    public void test1() throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(10); // 设置总数=10

        for (int i = 0; i < 10; ++i) {
            new Thread(() -> {
                try {
                    Thread.sleep(new Random().nextInt(3000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                countDownLatch.countDown(); // 每次计数-1
            }).start();
        }

        countDownLatch.await(); // 阻塞, 直至计数 <= 0

        System.out.println("计数<=0");

    }

    @Test
    public void test2() {
        CountDownLatch countDownLatch = new CountDownLatch(10);
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + " await前");
            try {
                countDownLatch.await();
                System.out.println(Thread.currentThread().getName() + " await后等待5s");
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " await后");
        }, "main-thread").start();

        for (int i = 0; i < 10; ++i) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " countDown前");
                countDownLatch.countDown();
                System.out.println(Thread.currentThread().getName() + " countDown后");
            }).start();
        }

        try {
            Thread.sleep(60000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void test3() {
        CountDownLatch countDownLatch = new CountDownLatch(10);
        for (int i = 0; i < 10; ++i) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " countDown前");
                countDownLatch.countDown();
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " countDown后");
            }).start();
        }
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + " await前");
            try {
                countDownLatch.await();
                System.out.println(Thread.currentThread().getName() + " await后等待5s");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " await后");
        }, "main-thread").start();

        try {
            Thread.sleep(60000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void test4() {
        CountDownLatch countDownLatch = new CountDownLatch(10);
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + " await前");
            try {
                countDownLatch.await();
                System.out.println(Thread.currentThread().getName() + " await后等待5s");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " await后");
        }, "main-thread").start();
        for (int i = 0; i < 10; ++i) {
            countDownLatch.countDown();
        }

        try {
            Thread.sleep(60000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
